package bank.internettoegang;

import fontys.util.NumberDoesntExistException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;
import bank.bankieren.*;
import bank.centraal.ICentraal;
import java.io.FileInputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Balie extends UnicastRemoteObject implements IBalie {

	private static final long serialVersionUID = -4194975069137290780L;
	private IBank bank;
	private HashMap<String, ILoginAccount> loginaccounts;
        private ICentraal centraal;
	//private Collection<IBankiersessie> sessions;
	private java.util.Random random;
        private ArrayList<IRemoteListener> listeners = new ArrayList<IRemoteListener>();

	public Balie(IBank bank, ICentraal central) throws RemoteException {
        //FileInputStream in = null;
        try {
            this.bank = bank;
            loginaccounts = new HashMap<String, ILoginAccount>();
            //sessions = new HashSet<IBankiersessie>();
            random = new Random();
            //loginaccounts.put("bart", new LoginAccount("bart", "b", 1));
            //loginaccounts.put("tobias", new LoginAccount("t", "t", 2));
           this.centraal = central;
        }
        catch (Exception ex) {
            Logger.getLogger(Balie.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally {
            try {
                //in.close();
            }
            catch (Exception ex) {
                Logger.getLogger(Balie.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

                        
	}

        public String getBankString()
        {
            return bank.getName();
        }
	public String openRekening(String naam, String plaats, String wachtwoord) {
		if (naam.equals(""))
			return null;
		if (plaats.equals(""))
			return null;

		if (wachtwoord.length() < 4 || wachtwoord.length() > 8)
			return null;

		int nr = bank.openRekening(naam, plaats);
		if (nr == -1)
			return null;

		String accountname = generateId(8);
		while (loginaccounts.containsKey(accountname))
			accountname = generateId(8);
		loginaccounts.put(accountname, new LoginAccount(accountname,
				wachtwoord, nr));

		return accountname;
	}

	public IBankiersessie logIn(String accountnaam, String wachtwoord)
			throws RemoteException {
		ILoginAccount loginaccount = loginaccounts.get(accountnaam);
                System.out.println("Hij krijgt: " + loginaccount.getNaam());
		if (loginaccount == null)
			return null;
		if (loginaccount.checkWachtwoord(wachtwoord)) {
			IBankiersessie sessie = new Bankiersessie(loginaccount
					.getReknr(), bank);
			
		 	return sessie;
		}
		else return null;
	}

	private static final String CHARS = "abcdefghijklmnopqrstuvwxyz0123456789";

	private String generateId(int x) {
		StringBuilder s = new StringBuilder();
		for (int i = 0; i < x; i++) {
			int rand = random.nextInt(36);
			s.append(CHARS.charAt(rand));
		}
		return s.toString();
	}


    public void addListener(IRemoteListener listener) throws RemoteException {
        listeners.add(listener);
        System.out.println("Listener add: " + listeners.size());
    }

    public void removeListener(IRemoteListener listener) throws RemoteException {
        listeners.remove(listener);
    }

    public boolean makeRemoteOver(int destination, Money money) throws RemoteException
    {
        boolean ret = bank.maakRemoteOver(destination, money);
        for(IRemoteListener listener : listeners){
                    listener.update(destination,bank.getRekening(destination).getSaldo().toString());
                    System.out.println("" + destination);
                    
         }

        return ret;
    }

    public boolean lokaalOpdracht(int source, int destination, Money money) throws RemoteException {
        boolean goedkeuring = false;
        System.out.println("Balie start: " + goedkeuring);
        try {
            if(bank.getRekening(destination) != null && bank.getRekening(source) != null) {
                goedkeuring = bank.maakOver(source, destination, money);
                System.out.println("maak lokaal over");
            }
            else
            {
                goedkeuring = centraal.maakRemoteOver(destination, money);
                if (goedkeuring)
                    bank.decreaseMoney(source, money);
                System.out.println("maak remote over");
            }
        } catch (NumberDoesntExistException ex) {
            Logger.getLogger(Balie.class.getName()).log(Level.SEVERE, null, ex);
        }

        if(listeners.isEmpty()){
            System.out.println("Hoo eens, geen listeners!");
        }

         for(IRemoteListener listener : listeners){
                    listener.update(source,bank.getRekening(source).getSaldo().toString());
                    System.out.println("" + source);
                    if(bank.getRekening(destination) != null)
                        listener.update(destination,bank.getRekening(destination).getSaldo().toString());
                    System.out.println("sending to "+listener.toString());
         }

        System.out.println("Balie succeswaarde: " + goedkeuring);
        return goedkeuring;
    }

    public boolean centraalBankOpdracht(int source, int destination, Money money) throws RemoteException {
        try {
            if(bank.getRekening(destination) != null && bank.getRekening(source) != null) {
                return bank.maakOver(source, destination, money);
                //inkomendOpdracht
            } else {
                //return centraal.maakOver(source, destination, money);
            }
        } catch (NumberDoesntExistException ex) {
            Logger.getLogger(Balie.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

}
